package freespiritsocial.io.user.ui.fragment.post

import android.graphics.Rect
import android.os.Bundle
import android.view.View
import android.view.ViewStub
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import com.google.android.material.appbar.AppBarLayout
import com.scwang.smart.refresh.layout.util.SmartUtil.dp2px
import com.shuyu.gsyvideoplayer.listener.VideoAllCallBack
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import com.to.aboomy.pager2banner.Banner
import freespiritsocial.io.user.R
import freespiritsocial.io.user.base.BaseFragment
import freespiritsocial.io.user.data.UserViewInfo
import freespiritsocial.io.user.data.model.bean.PostPojo
import freespiritsocial.io.user.databinding.FrgPostDetailBinding
import freespiritsocial.io.user.databinding.ViewStubBannerBinding
import freespiritsocial.io.user.databinding.ViewStubVideoBinding
import freespiritsocial.io.user.decoration.SpaceItemDecoration
import freespiritsocial.io.user.ext.*
import freespiritsocial.io.user.ui.activity.PerViewVideoAct
import freespiritsocial.io.user.ui.adapter.PostCommentsAdapter
import freespiritsocial.io.user.ui.adapter.PostImagesAdapter
import freespiritsocial.io.user.ui.fragment.mine.MineFrg
import freespiritsocial.io.user.ui.helper.PostMoreDialogHelper
import freespiritsocial.io.user.util.CacheUtil
import freespiritsocial.io.user.util.PreViewUtils
import freespiritsocial.io.user.viewmodel.PostDetailViewModel
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.navigateAction
import me.hgj.jetpackmvvm.util.StatusBarUtil
import kotlin.math.abs


/**
 * @description 帖子详情
 */
class PostDetailFrg: BaseFragment<PostDetailViewModel,FrgPostDetailBinding>() {

    companion object {
        const val KEY_DATA = "data"
    }

    var videoPlayer: StandardGSYVideoPlayer? = null
    var banner: Banner? = null
    lateinit var preViewUtils: PreViewUtils

    var commentHeadView: View? = null

    override fun layoutId(): Int = R.layout.frg_post_detail
    var curCommentId: Long? = null
    val adapter by lazy(LazyThreadSafetyMode.NONE) {
        PostCommentsAdapter(mViewModel).apply {
            goToPeople = {
                goToPeopleHome(it)
            }
            reply = {
                curCommentId = it
                mDatabind.etMessage.isFocusable = true
                mDatabind.etMessage.isFocusableInTouchMode = true
                mDatabind.etMessage.requestFocus()
                val imm: InputMethodManager? = getSystemService(requireContext(),InputMethodManager::class.java)
                imm?.showSoftInput(mDatabind.etMessage,0)
            }
        }
    }
    private val imagesAdapter by lazy(LazyThreadSafetyMode.NONE) {
        PostImagesAdapter(mViewModel.data.value?.fileList,corner = 0).apply {
            setOnItemClickListener { adapter,view,position ->
                val relPosition = banner!!.currentPager
                val bounds = Rect()
                view.getGlobalVisibleRect(bounds)
                preViewUtils.setBounds(bounds)
                preViewUtils.preImage(data[relPosition],relPosition)
            }
        }
    }
    var toolbarIsShow = false
        set(value) {
            field = value
            StatusBarUtil.darkMode(requireActivity(),!value)
        }
    val data get() = mViewModel.data.value

    override fun initView(savedInstanceState: Bundle?) = with(mDatabind) {
        mViewModel.data.value = arguments?.getParcelable<PostPojo>(KEY_DATA)
        model = mViewModel
        CacheUtil.getUser()?.userAvatar?.let { ivMyAvatar.circleImageUrl(it) }
        StatusBarUtil.darkMode(requireActivity(),false)
        click = Click()
        toolbar.setNavigationOnClickListener {
            nav().navigateUp()
        }
        initAppBarLayout(appbarLayout)
        stubBannerImages.viewStub?.setOnInflateListener(::initBanner)
        stubBannerVideo.viewStub?.setOnInflateListener(::initPlayer)
        if (data?.isVideo == true) {
            stubBannerVideo.viewStub?.inflate()
        } else {
            stubBannerImages.viewStub?.inflate()
        }
        recyclerViewComments.init(adapter,emptyText = "No one has commented yet, let's write the first comment.",emptyImage = R.mipmap.empty_comments)
            .addItemDecoration(SpaceItemDecoration(dp2px(20f),dp2px(20f)))
        etMessage.setOnFocusChangeListener { _,hasFocus ->
            flTip.isVisible = !hasFocus
        }
    }

    private fun getCommentHeadView() {
        commentHeadView?.let {
            updateCommentView()
            return
        }
        if (data?.commentCount == 0) return
        layoutInflater.inflate(R.layout.item_post_detail_comment_header,null).apply {
            adapter.setHeaderView(this)
            commentHeadView = this
            updateCommentView()
        }
    }

    private fun updateCommentView() = with(commentHeadView) {
        this ?: return@with
        data?.commentAvatars?.getOrNull(0)?.let {
            val iv = this.findViewById<ImageView>(R.id.iv1)
            iv.circleImageUrl(it)
            iv.isVisible = true
        }
        data?.commentAvatars?.getOrNull(1)?.let {
            val iv = this.findViewById<ImageView>(R.id.iv2)
            iv.circleImageUrl(it)
            iv.isVisible = true
        }
        data?.commentAvatars?.getOrNull(2)?.let {
            val iv = this.findViewById<ImageView>(R.id.iv3)
            iv.circleImageUrl(it)
            iv.isVisible = true
        }
        this.findViewById<TextView>(R.id.tv_comment).text = "${data?.commentCountStr} comments"
        this.findViewById<TextView>(R.id.tv_likes_and_name).text =
            "${data?.commentUserName?.substring(0,4)}... and ${data?.likeCountStr} liked"
    }

    private fun goToPeopleHome(id: String?) {
        mViewModel.getUserInfo(id) {
            nav().navigateAction(R.id.mineFrg,bundleOf(MineFrg.KEY_IS_USER to false,MineFrg.KEY_USER to it))
        }
    }

    override fun createObserver() {
        super.createObserver()
        mViewModel.data.observe(this) {
            getCommentHeadView()
        }
        mViewModel.commentResult.observe(this) {
            adapter.data.addAll(it.data)
            adapter.notifyDataSetChanged()
        }
        eventViewModel.keyBoardShowEvent.observe(this) {
            if (it.not()) {
                mDatabind.etMessage.clearFocus()
                curCommentId = null
            }
        }
        eventViewModel.delPostEvent.observe(this) {
            nav().navigateUp()
        }
        eventViewModel.savePostEvent.observe(this) {
            if (data?.invitationId == it) {
                data?.isSave = data?.isSave?.not()
                mViewModel.data.value = data
            }
        }
        eventViewModel.hidePostEvent.observe(this) {
            if (data?.invitationId == it) {
                nav().navigateUp()
            }
        }
        eventViewModel.attentionEvent.observe(this) {
            if (data?.userId == it) {
                data?.isFollow = data?.isFollow?.not()
                mViewModel.data.value = data
            }
        }
        eventViewModel.likePostEvent.observe(this) {
            if (data?.invitationId == it) {
                data?.isLike = data?.isLike?.not()
                data?.likeCount = data?.likeCount?.plus(if (data?.isLike == true) 1 else -1) ?: 0
                mViewModel.data.value = data
            }
        }
    }

    /**
     * 初始化轮播图
     */
    private fun initBanner(stub: ViewStub,inflated: View) {
        val dataViewStub: ViewStubBannerBinding = DataBindingUtil.bind(inflated) ?: return
        dataViewStub.bannerImages.initDefBottomIndicator(requireContext())
        dataViewStub.bannerImages.isAutoPlay = false
        dataViewStub.bannerImages.adapter = imagesAdapter
        banner = dataViewStub.bannerImages
        preViewUtils = PreViewUtils(requireActivity(),imagesAdapter.data.mapIndexedTo(arrayListOf<UserViewInfo>()) { index,url ->
            UserViewInfo(url,index)
        })
    }

    override fun lazyLoadData() {
        mViewModel.getComments()
    }

    /**
     * 初始化标题栏折叠
     */
    private fun initAppBarLayout(appbarLayout: AppBarLayout) {
        appbarLayout.addOnOffsetChangedListener(object: AppBarStateChangeListener() {
            override fun onStateChanged(appBarLayout: AppBarLayout?,state: State?) {
                when (state) {
                    State.EXPANDED -> {
                        //展开状态
                        toolbarIsShow = true
                        mDatabind.toolbar.setNavigationIcon(R.mipmap.icon_back)
                        mDatabind.ivMore.setImageResource(R.mipmap.icon_more_with_bg)
                    }
                    State.COLLAPSED -> {
                        //折叠状态
                        toolbarIsShow = false
                        mDatabind.toolbar.setNavigationIcon(R.mipmap.arrow_left_black)
                        mDatabind.ivMore.setImageResource(R.mipmap.icon_appbar_more)
                    }
                    else -> {
                        //中间状态
                    }
                }
            }
        })
    }

    /**
     * 初始化播放器
     */
    private fun initPlayer(stub: ViewStub,inflated: View) {
        val dataViewStub: ViewStubVideoBinding = DataBindingUtil.bind(inflated) ?: return
        videoPlayer = dataViewStub.videoPlayer
        videoPlayer?.thumbImageView = ImageView(requireContext()).apply {
            loadImage(data?.coverUrl)
        }
        videoPlayer?.setUpLazy(data?.fileUrl,true,null,null,"")
        videoPlayer?.backButton?.isVisible = false
        videoPlayer?.fullscreenButton?.isVisible = false
        videoPlayer?.setVideoAllCallBack(object: VideoAllCallBack {
            override fun onStartPrepared(url: String?,vararg objects: Any?) {
            }

            override fun onPrepared(url: String?,vararg objects: Any?) {
            }

            override fun onClickStartIcon(url: String?,vararg objects: Any?) {
            }

            override fun onClickStartError(url: String?,vararg objects: Any?) {
            }

            override fun onClickStop(url: String?,vararg objects: Any?) {
            }

            override fun onClickStopFullscreen(url: String?,vararg objects: Any?) {
            }

            override fun onClickResume(url: String?,vararg objects: Any?) {
            }

            override fun onClickResumeFullscreen(url: String?,vararg objects: Any?) {
            }

            override fun onClickSeekbar(url: String?,vararg objects: Any?) {
            }

            override fun onClickSeekbarFullscreen(url: String?,vararg objects: Any?) {
            }

            override fun onAutoComplete(url: String?,vararg objects: Any?) {
            }

            override fun onComplete(url: String?,vararg objects: Any?) {
            }

            override fun onEnterFullscreen(url: String?,vararg objects: Any?) {
            }

            override fun onQuitFullscreen(url: String?,vararg objects: Any?) {
            }

            override fun onQuitSmallWidget(url: String?,vararg objects: Any?) {
            }

            override fun onEnterSmallWidget(url: String?,vararg objects: Any?) {
            }

            override fun onTouchScreenSeekVolume(url: String?,vararg objects: Any?) {
            }

            override fun onTouchScreenSeekPosition(url: String?,vararg objects: Any?) {
            }

            override fun onTouchScreenSeekLight(url: String?,vararg objects: Any?) {
            }

            override fun onPlayError(url: String?,vararg objects: Any?) {
            }

            override fun onClickStartThumb(url: String?,vararg objects: Any?) {
            }

            override fun onClickBlank(url: String?,vararg objects: Any?) {
                PerViewVideoAct.launch(requireContext(),UserViewInfo(data?.fileUrl,data?.coverUrl,0))
            }

            override fun onClickBlankFullscreen(url: String?,vararg objects: Any?) {
            }
        })
        //是否可以滑动调整
        videoPlayer?.setIsTouchWiget(true)
        videoPlayer?.isLooping = true
        videoPlayer?.startPlayLogic()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (hidden) {
            StatusBarUtil.darkMode(requireActivity())
            videoPlayer?.onVideoPause()
        } else {
            StatusBarUtil.darkMode(requireActivity(),toolbarIsShow.not())
            videoPlayer?.onVideoResume()
        }
    }

    override fun onPause() {
        super.onPause()
        videoPlayer?.onVideoPause()
    }

    override fun onStart() {
        super.onStart()
        videoPlayer?.isVisible = true
    }

    override fun onStop() {
        super.onStop()
        videoPlayer?.isVisible = false
    }


    override fun onDestroyView() {
        StatusBarUtil.darkMode(requireActivity())
        videoPlayer?.let {
            it.setVideoAllCallBack(null)
        }
        super.onDestroyView()
    }

    inner class Click {
        fun send() {
            mViewModel.comment(curCommentId) {
                adapter.data.clear()
                hideSoftKeyboard(requireActivity())
                mViewModel.commentContent.set("")
                mViewModel.getComments {
                    mViewModel.getPost(data?.invitationId)
                }
            }
        }

        fun goToPeopleHome() {
            goToPeopleHome(data?.userId)
        }

        fun more() {
            hideSoftKeyboard(mDatabind.etMessage)
            PostMoreDialogHelper(this@PostDetailFrg,mViewModel.data.value!!,mViewModel).create()
        }

        fun follow() {
            mViewModel.attention(data?.userId,data?.isFollow == true)
        }

        fun like() {
            mViewModel.likePost(data?.invitationId)
        }
    }

    abstract class AppBarStateChangeListener: AppBarLayout.OnOffsetChangedListener {
        enum class State {
            EXPANDED, COLLAPSED, IDLE
        }

        private var mCurrentState = State.IDLE

        override fun onOffsetChanged(appBarLayout: AppBarLayout,i: Int) {
            mCurrentState = when {
                i == 0 -> {
                    if (mCurrentState != State.EXPANDED) {
                        onStateChanged(appBarLayout,State.EXPANDED)
                    }
                    State.EXPANDED
                }
                abs(i) >= appBarLayout.totalScrollRange -> {
                    if (mCurrentState != State.COLLAPSED) {
                        onStateChanged(appBarLayout,State.COLLAPSED)
                    }
                    State.COLLAPSED
                }
                else -> {
                    if (mCurrentState != State.IDLE) {
                        onStateChanged(appBarLayout,State.IDLE)
                    }
                    State.IDLE
                }
            }
        }

        abstract fun onStateChanged(appBarLayout: AppBarLayout?,state: State?)
    }
}